    import java.io.BufferedReader; 
    import java.io.BufferedWriter; 
    import java.io.DataInputStream;
    import java.io.FileInputStream;
	import java.io.IOException; 
	import java.io.InputStreamReader; 
	import java.io.OutputStream;
	import java.io.FileReader;
	import java.io.FileWriter;
	import java.util.Calendar;
	import java.util.Random;
	import java.util.StringTokenizer;
	import java.security.KeyManagementException;
	import java.security.NoSuchAlgorithmException;
	import javax.net.ssl.SSLContext;
	import javax.net.ssl.SSLSocket;
	import javax.net.ssl.X509TrustManager;
	import java.security.cert.X509Certificate;
import java.net.*;
	public class bot 
	{ 
		static String server=new String("irc.bynets.org"); 
	    static String chanel=new String("#850501"); 
	    static String nameBot=new String("Grafik");
	    static String passwordNick=new String("2808188");
	    static String login=new String("BOT");
	    static String password=new String("1234321");
	    static int PRIV = 0;
	    static String chanels=chanel+" ";
        static int komand=0;
        static String owner=""; 
        static boolean owned=false;  
		public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException
	    { 
	    	try
	    	{
	    	SSLContext sslcontext = SSLContext.getInstance("SSL");//создаем хранилище ключей
	    	
            sslcontext.init(null, new X509TrustManager[]{new MyTrustManager()}, null);//регистрируем хранилище ключей (здесь лежат ключи с помощью которых происходит шифрование в SSL)
            
	    	javax.net.ssl.SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory(); //настройка сокета через sslcontext
	    
	    	//InetAddress address = InetAddress.getByName(server);
	    	//Socket socket = new Socket(address, 6667);
	        System.out.println("connecting to: "+server); 
	        SSLSocket socket = (SSLSocket) sslSocketFactory.createSocket(server, 6697);
	        System.out.println("connected to "+socket.getInetAddress().getHostName()+" to port "+socket.getPort()); 
	        socket.startHandshake();
	        
	        DataInputStream in=new DataInputStream(socket.getInputStream()); 
	        OutputStream out=socket.getOutputStream(); 
	       
	        BufferedReader br=new BufferedReader(new InputStreamReader(in,"cp1251")); 
	        out.write(("NICK "+nameBot+"\r\n").getBytes()); 
	        out.write("USER BOT 8 * :SAPOG\r\n".getBytes());
	        String s = new String();
	        
	       while((s = br.readLine())!= null)
	        {
	        	System.out.println(s); 
	        	if(s.contains("PING")) pong(s,out);
	        	out.write(("MODE "+nameBot+" -i"+"\r\n").getBytes());
	        	out.write(("JOIN "+chanel+"\r\n").getBytes()); 
	      	    if(s.contains("JOIN"))break;
	       }
	       // printInChat("HELLO WORLD!!!", out);
	        String priv=new String();
	        while((s = br.readLine())!= null)
	        { 
	            System.out.println(s); 
	            if(s.contains("PING")) 
	            {
	            	pong(s,out);
	                komand=1;
	            } 
	            if(s.contains("!help"))
	    		{
	    			komand=1;
	    			help(s,out);
	    		}
	            if(owned)
	            { 
	                if(s.substring(0, owner.length()).equals(owner))
	                { 
	                	commands(s,out);//функция для команд
    	    	    	if(s.contains("PRIVMSG "+nameBot) && s.contains("выход из программы!")) return;
	                }
	            }
	            if(s.contains("IDENTIFY "+login+" "+password))
	            { 
	            	identify(s,out);
	            } 
	            else
	            {
	            	if(s.contains("PRIVMSG "+nameBot) && komand==0)
	    			{	 
	            		PRIV=1;
		            	priv=new String(s.substring(1,s.indexOf("!")));
	   					otvet(s,priv,out);
	    			}
	            	else if (s.contains("PRIVMSG #") && s.contains(nameBot) && komand==0 && owned)
	            	{
	            		PRIV=0;
	            		priv=new String(s.substring(1,s.indexOf("!")));
	            		StringTokenizer chan=new StringTokenizer(chanels," ");
	            		while(chan.hasMoreTokens())
	            		{
	            			String a=chan.nextToken();
	            			StringTokenizer chan2=new StringTokenizer(s," ");
	            			while(chan2.hasMoreTokens())
	            			{
	            				String b=chan2.nextToken();
	            				if(a.equals(b)) {chanel=a; break;}
	            			}
	            		}
	   					otvet(s,priv,out);
	            	}
	            }
	            komand=0;
	        }
	    	}
	    	catch(IOException ex)
	    	{
	    		System.out.println(ex.toString());
	    	}
	    }
	    public static void otvet(String s,String priv, OutputStream out) throws NullPointerException, IOException
	    { 
	    	BufferedReader reader = new BufferedReader(new InputStreamReader (new FileInputStream("tatler.txt"),"cp1251"));
	    	String line, l;  
	    	l=s.substring(s.lastIndexOf(":")+1);
	    	BufferedWriter inn = new BufferedWriter(new FileWriter(priv+".txt", true));
	    	inn.write(Calendar.getInstance().getTime()+" "+priv + " " + l+"\r\n");
	    	int numvopr=0, numvopr2=0, rec=0;
	    	int kolvo=0;
			String proverka,proverka2;
			int vopros=0;
			int maxposled=0, recposled=0, numvoprposled=0;
			String buffer="";
			
			double allwords=0;
			double procent=0;
			int numvoprproc=0;
			
	    	while((line = reader.readLine())!= null)
	    	{
	    		if(line.contains(">"))
	    		{
	    			numvopr++;
	    			kolvo=0;
	    			maxposled=0;
	    			StringTokenizer fa=new StringTokenizer(line," >?");//разбиваем вопрос на слова
	    			allwords=fa.countTokens();
	    			String posl="";
    				while(fa.hasMoreTokens()) 
    				{
    					posl+=" "; 
    					posl+=fa.nextToken();
    				}
	    			if(l.contains("?")) vopros=1;
	    			StringTokenizer vopr=new StringTokenizer(l," ?"); //разбиваем вопрос на слова
	    			allwords=vopr.countTokens();
	    			while(vopr.hasMoreTokens())
	    			{
	    				proverka=vopr.nextToken();
	    				StringTokenizer f=new StringTokenizer(line," >?");
	    				while(f.hasMoreTokens())//сравниваем слова в предложениях
	    				{
	    					proverka2=f.nextToken();
	    					if(proverka.equals(proverka2)) 
	    					{
	    						buffer+=proverka2;
	    						if(posl.contains(buffer))
	    							{
	    								maxposled++;
	    								buffer+=" ";
	    							}
	    						else 
	    						{
	    							if(recposled<=maxposled) 
	    							{
	    								recposled=maxposled;
	    								numvoprposled=numvopr;
	    							} 
	    							buffer="";
	    							maxposled=0;
	    		    			}
	    						kolvo++;
	    					}
	    				}
	    			}
	    			if(recposled<=maxposled) //берем номер ответа с максимальной последовательностью слов между вопросом и ответом
					{
						recposled=maxposled;
						numvoprposled=numvopr;
					} 
	    			if(allwords!=0 && procent<kolvo/allwords)//берем номер ответа, если вопрос почти равен вопросу, находящемуся в базе
	    			{
	    				procent=kolvo/allwords;
	    				numvoprproc=numvopr;
	    			}
	    			if(rec<=kolvo) //берем номер ответа с большим количеством совпадения слов
	    			{
	    				rec=kolvo; 
	    				numvopr2=numvopr;
	    			}
	    		}
	    	}
	    	reader.close();
	    	BufferedReader reader2 = new BufferedReader(new InputStreamReader (new FileInputStream("tatler.txt"),"cp1251"));
	    	int number=0;
	    	Random randmsg=new Random();
    		int b;
    		int c=0, est=0;
    		int VO=0;
    		
    		
	    	if(vopros==1 && rec==0) //если ничего похожего в базе не найденно
	    	{
	    		while((line = reader2.readLine())!= null)
		    	{
	    			if(line.contains(">?"))
	    			{
	    				while((line=reader2.readLine())!= null) { c++; if(line.contains(">")) break; }
	    				b=randmsg.nextInt(c-2);
	    				BufferedReader reader4 = new BufferedReader (new InputStreamReader (new FileInputStream("c:\\tatler.txt"),"cp1251"));
	    				c=0;
	    				if(b==0) b=1;
	    				while((line = reader4.readLine())!=null)
	    				{
	    					if(line.contains(">?"))
	    					{
		    				    while(c!=b){line=reader4.readLine();c++;}
		    					if(PRIV==1)printInPrivate(line,priv,out);
				    			else printInChat(line,out);
		    					inn.write(Calendar.getInstance().getTime()+" "+nameBot + " " + line+"\r\n");
		    					System.out.println("PRIVMSG"+priv+" :"+line);
		    					est=1;
				    			break;
	    					}
	    				}
	    			}
	    			if(est==1) return;
		    	}
	    	}
	    	if(numvopr2==numvoprproc && numvopr2==numvoprposled && rec!=0) VO=1;
    		if(procent>=0.8) VO=2;
    		else 
    		{
    			if(recposled/allwords>=0.5) VO=3;
    			else VO=4;
    		}
	    	if(VO==1 || VO==4) while((line = reader2.readLine())!= null )//вывод ответа с большим количеством совпадений слов
	    	{
	    		if(line.contains(">")) number++;
	    		if(number==numvopr2) 
	    		{			
	    	    	while((line=reader2.readLine())!= null) { c++; if(line.contains(">")) break; }
	    	    	b=randmsg.nextInt(c-2);
	    	    	BufferedReader reader4 = new BufferedReader (new InputStreamReader (new FileInputStream("tatler.txt"),"cp1251"));
	    	    	c=0;
	    	    	if(b==0) b=1;
	    	    	number=0;
	    	    	while((line = reader4.readLine())!=null)
	    	    	{
	    	    		if(line.contains(">")) number++;
	    	    		if(number==numvopr2)
	    	    		{
	    		    	    while(c!=b){line=reader4.readLine();c++;}
	    		    		if(PRIV==1)printInPrivate(line,priv,out);
	    					else printInChat(line,out);
	    		    		inn.write(Calendar.getInstance().getTime()+" "+nameBot + " " + line+"\r\n");
	    		    		est=1;
	    					break;
	    	    		}
	    	    	}
	    		}
	    		if(est==1) break;
	    	}
	    	
	    	reader2.close();
	    	if(VO==3)
	    	{
	    		BufferedReader reader3 = new BufferedReader(new InputStreamReader (new FileInputStream("tatler.txt"),"cp1251"));
		    	number=0;
		    	
		    	while((line = reader3.readLine())!= null)//вывод ответа с большей последовательностью
		    	{
		    		if(line.contains(">")) number++;	
		    		if(number==numvoprposled)
		    		{
		    			line=reader3.readLine();
		    			if(PRIV==1)printInPrivate(line,priv,out);
		    			else printInChat(line,out);
		    			inn.write(Calendar.getInstance().getTime()+" "+nameBot + " " + line+"\r\n");
		    			break;
		    		}
		    	}
		    	reader3.close();
		    }
	    	
	    	if(VO==2)
	    	{
	    		BufferedReader reader5 = new BufferedReader(new InputStreamReader (new FileInputStream("tatler.txt"),"cp1251"));
		    	number=0;
		    	
		    	while((line = reader5.readLine())!= null)
		    	{
		    		if(line.contains(">")) number++;	
		    		if(number==numvoprproc)
		    		{
		    			line=reader5.readLine();
		    			if(PRIV==1)printInPrivate(line,priv,out);
		    			else printInChat(line,out);
		    			inn.write(Calendar.getInstance().getTime()+" "+nameBot + " " + line+"\r\n");
		    			break;
		    		}
		    	}
		    	reader5.close();
		    }
	    	inn.close();
	    	System.out.println("PRIVMSG "+priv+" :"+line);
	    }
	    public static void printInPrivate(String s,String priv, OutputStream out) throws NullPointerException, IOException
	    { 
	        out.write(("PRIVMSG "+priv+" :"+s+"\r\n").getBytes("cp1251")); 
	    }
	    public static void printInChat(String s, OutputStream out) throws NullPointerException, IOException
	    { 
	        out.write(("PRIVMSG "+chanel+" :"+s+"\r\n").getBytes("cp1251")); 
	    } 
	    public static void printAnecdot(String s, int k, OutputStream out) throws NullPointerException, IOException
	    {
	    	 BufferedReader reader = new BufferedReader(new FileReader("Anec.txt"));
	    	 for(int i=0;i<k; i++) s=reader.readLine();
	    	 out.write(("PRIVMSG "+chanel+" :"+s+"\r\n").getBytes("cp1251"));
	    }
	    public static void pong(String s, OutputStream out) throws IOException
	    {
	    	out.write(("PONG "+s.substring(4)).getBytes());
	    }
	    public static void identify(String s, OutputStream out) throws NullPointerException, IOException
	    {
	    	owner=new String(s.substring(0,s.indexOf("!"))); 
            owned=true;
            String ss=new String("мой хозяин --");
            ss+=owner;
            printInChat(ss, out);
            printInPrivate("Вы идентифицированы!",s.substring(1,s.indexOf("!")),out);
            System.out.println("мой хозяин -- "+owner); 
	    }
	    public static void help(String s, OutputStream out)throws NullPointerException, IOException
	    {
	    	printInPrivate("Добро пожаловать в помощь по работе с ботом!",s.substring(1,s.indexOf("!")),out);
			printInPrivate("************************************************************************************************************************",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Команды для всех пользователей :",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Идентификация у бота в качестве администратора: IDENTIFY <login> <password>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("************************************************************************************************************************",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Команды для администратора бота :",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот зарегистрировал свой ник введите команду: зарегись",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Для захода бота на какой-либо канал введите команду: зайди на <#канал>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Для выхода бота из какого-либо канала введите команду: выйди из <#канал>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот сказал анекдот введите команду: анекдот",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот добавил пользователя в список HOP'ов канала введите команду: дать HOP для <ник>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот добавил пользователя в список AOP'ов канала введите команду: дать AOP для <ник>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот добавил пользователя в список SOP'ов канала введите команду: дать SOP для <ник>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот добавил пользователя в список VOP'ов канала введите команду: дать VOP для <ник>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот удалил пользователя из списка HOP'ов канала введите команду: дать HOP для <ник>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот удалил пользователя из списка AOP'ов канала введите команду: дать AOP для <ник>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот удалил пользователя из списка SOP'ов канала введите команду: дать SOP для <ник>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Чтобы бот удалил пользователя из списка VOP'ов канала введите команду: дать VOP для <ник>",s.substring(1,s.indexOf("!")),out);
			printInPrivate("Для завершения работы бота введите команду: выход из программы!",s.substring(1,s.indexOf("!")),out);
			printInPrivate("*************************************************************************************************************************",s.substring(1,s.indexOf("!")),out);
	    }
	    public static void commands(String s, OutputStream out)
	    {
	    	try
	    	{
		    	if(s.contains("анекдот")) 
	        	{
		    		komand=1; 
		    		Random rand=new Random();
		    		printAnecdot(s, rand.nextInt(113), out);
		    	}
		    	if(s.contains("PRIVMSG "+nameBot) && s.contains("зайди на"))
	        	{
	            	komand=1; 
	            	out.write(("JOIN "+s.substring(s.lastIndexOf("#"))+"\r\n").getBytes()); 
	            	chanels+=s.substring(s.lastIndexOf("#"))+" ";
	        	}
		    	if(s.contains("PRIVMSG "+nameBot) && s.contains("выйди из"))
			    {
					komand=1; 
					out.write(("PART "+s.substring(s.lastIndexOf("#"))+"\r\n").getBytes());
					if(chanels.contains(s.substring(s.lastIndexOf("#")))) chanels=chanels.replace(s.substring(s.lastIndexOf("#")), "");
				}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("зарегись"))
			        {komand=1; out.write(("NickServ IDENTIFY "+passwordNick+"\r\n").getBytes());}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("дать VOP для"))
					{komand=1; out.write(("ChanServ VOP #850501 ADD "+s.substring(s.lastIndexOf(" ")+1)+"\r\n").getBytes());}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("дать SOP для"))
					{komand=1; out.write(("ChanServ SOP #850501 ADD "+s.substring(s.lastIndexOf(" ")+1)+"\r\n").getBytes());}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("дать AOP для"))
					{komand=1; out.write(("ChanServ AOP #850501 ADD "+s.substring(s.lastIndexOf(" ")+1)+"\r\n").getBytes());}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("дать HOP для"))
					{komand=1; out.write(("ChanServ HOP #850501 ADD "+s.substring(s.lastIndexOf(" ")+1)+"\r\n").getBytes());}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("убрать VOP для"))
					{komand=1; out.write(("ChanServ VOP #850501 DEL "+s.substring(s.lastIndexOf(" ")+1)+"\r\n").getBytes());}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("убрать SOP для"))
			    	{komand=1; out.write(("ChanServ SOP #850501 DEL "+s.substring(s.lastIndexOf(" ")+1)+"\r\n").getBytes());}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("убрать AOP для"))
					{komand=1; out.write(("ChanServ AOP #850501 DEL "+s.substring(s.lastIndexOf(" ")+1)+"\r\n").getBytes());}
				if(s.contains("PRIVMSG "+nameBot) && s.contains("убрать HOP для"))
		    		{komand=1; out.write(("ChanServ HOP #850501 DEL "+s.substring(s.lastIndexOf(" ")+1)+"\r\n").getBytes());}  
			    
	    	}
		    catch(IOException ex)
	    	{
	    		System.out.println(ex.toString());
	    	}
	    }
	}
	class MyTrustManager implements X509TrustManager
	{
	    public void checkClientTrusted(X509Certificate[] chain, String authType) {
	    }

	    public void checkServerTrusted(X509Certificate[] chain, String authType) {
	    }

	    public X509Certificate[] getAcceptedIssuers() {
	        return null;
	    }
	}